
public class HitCount {

	private static final int MAX_QUEUE = 0xfffff;
	private int capacity;
	private int unit;
	private int[] queue;
	private int totHit;
	private long startTime;
	private int size;

	public HitCount(int sec) {
		capacity = Math.min(MAX_QUEUE, sec * 1000);
		unit = sec * 1000 / capacity;
		startTime = 0;
		size = 0;
		totHit = 0;
		queue = new int[capacity];
	}

	public void hit() {
		long curTime = currentTime();
		clip(curTime);
		queue[(int) (curTime % capacity)]++;
		totHit++;
	}

	public int count() {
		long curTime = currentTime();
		clip(curTime);
		return totHit;
	}

	private void clip(long curTime) {
		while (startTime + capacity <= curTime && size > 0) {
			totHit -= queue[(int) (startTime % capacity)];
			queue[(int) (startTime % capacity)] = 0;
			startTime++;
			size--;
		}
		startTime = Math.max(startTime, curTime - capacity + 1);
		size = (int) (curTime - startTime + 1);
	}

	private long currentTime() {
		return System.currentTimeMillis() / unit;
	}

	public static void main(String[] args) {
		HitCount hit = new HitCount(3);
		for (int i = 0; i < 1000; ++i) {
			hit.hit();
			try {
				Thread.sleep(10 * (int) Math.pow(10, i / 10));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(hit.count());
		}
	}
}
